#ifndef DATACONTAINER_H_
#define DATACONTAINER_H_

#include <vector>
#include <string>
#include <map>
#include <iterator>
#include "IDataContainer.h"
#include "PConvertor.h"
#include "UnknownTypeException.h"


namespace PComunicator
{

//! DataContainer class.
/*!
Trieda implementujuca IDataContainer rozhranie.
*/
class DataContainer : public IDataContainer
{
	public:
		//! Constructor
		/*!
			Zakladny konstruktor v ktorom je vytvorena zakladna sada prikazov.
		*/
		DataContainer(void);
		~DataContainer(void);

		//! AddCommand
		/*!
			Prida prikaz do DataContainer ktory sa potom nasledne posle druhej strane.
			V pripade ak theOverwrite je nastaveny na true a zaroven uz nejaky prikaz
			bol zadany tak ten sa prepise novym prikazom v opacnom pripade sa zachova
			uz zadany prikaz.

			\param theCommand novy prikaz na pridanie do kontajnera
			\param theOverwrite urcuje ci sa stary prikaz ma prepisat alebo ne
		*/
		virtual bool AddCommand(std::string theCommand, bool theOverwrite);

		//! GenerateOutput
		/*!
			Produkuje vystup v forme formatovaneho pola ktory v sebe obsahuje
			zakodovanu celu triedu DataContainer a jej obsah.

			\param theOutput vystupne pole byte (unsigned char)
			\param theSize urcuje velkost vystupneho pola
			\return hodnotu true v pripade ak generovanie pola prebehlo v poriadku, inak vracia false
		*/
		virtual bool GenerateOutput(std::vector<byte> &theOutput);

		//! Parse
		/*!
			Sluzi na analyticky rozbor formatovaneho pola byte(unsigned char) ktoreho
			rozborom sa naplni vlastna trieda DataContainer. Format pola je strikne dany
			a ktory je tvoreny funkciou GenerateOutput.

			\param theInput vstupne formatovane pole
			\param theSize urcuje velkost vstupneho pola
			\return hodnotu true v pripade ak analyza pola prebehla v poriadku, inak vracia false
		*/
		virtual bool Parse(const std::vector<byte> &theInput);

		
		//! GetCommand
		/*!
			Ziska aktualne nastaveny prikaz 

			\return hodnotu(char) prikazu
		*/
		char GetCommand();


	private:
		std::map<std::string,char,std::greater<std::string> > myCommands;
		char myActualCommand;
		std::vector<byte> DataFormater(boost::any theData);
		bool GetData(std::vector<byte> theInput,byte theType,boost::any &aData);
		char GetDatatypeCode(boost::any theData);
};

}
#endif

